home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Frameworks / Hsoi's App Shell 1.0a4 / Hsoi's App Shell Source / HASUtilPStrings.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-28  |  12.0 KB  |  400 lines  |  [TEXT/CWIE]

  1. /*
  2.     HASUtilPStrings.c from Hsoi's App Shell ©1995-1997 John C. Daub.  All rights reserved.
  3.     
  4.     This file is a collection of various functions that allow you to deal with Pascal
  5.     type strings (since using ANSI C library functions, like strcpy just can't work
  6.     that well on Pascal strings...which is what the MacOS uses).
  7.     
  8.     So you know, there are also some C-glue functions that you can use...
  9.     these functions allow you to use C style strings instead of Pascal style
  10.     strings when calling toolbox routines.  to use these C-glue functions, 
  11.     first you have to know if your compiler supports it.  For more information
  12.     about it, you can check the ConditionalMacros.h file and look for this
  13.     symbol:  CGLUESUPPORTED.  If you'd like to be lazy, from what ConditionalMacros.h
  14.     says, it seems that only THINK C cannot support the C-glue functions.
  15.     
  16.     To find the functions you can use, you can just enter the CGLUESUPPORTED into
  17.     your Find dialog and search through all your Universal Header files.  That'll
  18.     turn you up a lot of information.
  19.     
  20.     Also, you'll need to make sure you have a C-glue library in your project.  In
  21.     Metrowerks CodeWarrior (which is what I use) there is a file called CGlue.c
  22.     in the MacOS Support:Libraries:MacOS 68k:MacOS Files folder.  You'll need this
  23.     (I assume) to use these functions.  However, I didn't find a PPC version of
  24.     the CGlue.c file...i don't know if you can just use the same CGlue.c file
  25.     in PPC projects or not, or even if CGlue is supported on PowerMacs....honestly,
  26.     I don't use this stuff, so I've not tried...give it a whirl if you care to
  27.     try and let me know how it turns out! :)
  28.     
  29.     Also, there's a file called PLStringFuncs.h.  Never used it nor the stuff
  30.     within it, but it's a C string conversion for Pascal file.  Give it some
  31.     investigation if you'd like (and don't forget to add in the proper
  32.     libs for 68k and PPC for using the PLStringFuncs)...it might be useful.
  33.     
  34.     But in the end, I just like using what I have here...they're quick, simple
  35.     and easy, and no need to have to link in external libraries just to use
  36.     one or two functions.
  37. */
  38.  
  39. #pragma mark ••• #includes •••
  40.  
  41. #include "HASUtilPStrings.h"
  42.  
  43. #pragma mark -
  44. #pragma mark ••• HAS String Functions •••
  45.  
  46. /* pStringCopy: copy one Pascal string to another */
  47.  
  48. void    HsoipStringCopy( ConstStr255Param srcString, Str255 destString )
  49. {
  50.     register short    index;
  51.     
  52.     index = srcString[0] + 1;
  53.     
  54.     while( index-- )
  55.     {
  56.         *destString++ = *srcString++;
  57.     }
  58.     
  59.     return;
  60. }
  61.  
  62. /*    
  63.     ConcatString: concatenate two Pascal strings.  s2 will be tacked onto
  64.     the end of s1 (s1 will now be modified and contain the whole thing, s2
  65.     will be "unchanged"
  66. */
  67.  
  68. void    HsoiConcatString( Str255 s1, Str255 s2 )
  69. {
  70.     register unsigned char    index1, index2;
  71.     
  72.     if ( s2[ 0 ] == 0 )
  73.         return;
  74.     
  75.     if ( ( (short)s1[0] + (short)s2[0] ) > 255 )
  76.         return;
  77.     
  78.     for ( index1 = s1[0] + 1, index2 = 1; index2 <= s2[ 0 ]; index1++, index2++ )
  79.     {
  80.         s1[ index1 ] = s2[ index2 ];
  81.     }
  82.     
  83.     s1[0] += s2[0];
  84.     
  85.     return;
  86. }
  87.  
  88. // HsoiStripDecimal is sorta an obsolete function.  i was using it at one
  89. // time in HAS as i was porting some Pascal functions to C (combinations of
  90. // the pascal functions pos with insert and delete).  However, with the way
  91. // things turned out, this function became unnecessary, however i still felt
  92. // like keeping it around just to show you another example and fun with
  93. // manipulating strings.
  94.  
  95. // what this does is strip the decimal point out of a given string (srcStr)
  96. // and returns the stripped string (strippedStr).  for example, if you have
  97. // 1.3, you'll return 13.  if you have 123.456, you'll get 123456.  if
  98. // 123, 123.  get it?  it's probably not that useful ouside of what it was
  99. // originally written for (doubt it has much worth outside of that), but it's
  100. // cute to look at at least.
  101.  
  102. void    HsoiStripDecimal( ConstStr255Param srcStr, Str255 strippedStr )
  103. {
  104.     register short    i, j;
  105.     Boolean            srcHasDecimal = false;  // assume it won't
  106.     
  107.     // first, we make sure there even is a decimal point in the strStr to strip.
  108.     // if there isn't, makes our life easier :)
  109.     
  110.     for ( i = 1; i <= 255; i++ )
  111.     {
  112.         if ( srcStr[i] == '.' )
  113.         {
  114.             srcHasDecimal = true;
  115.             break; // might as well can out
  116.         }
  117.     }
  118.     
  119.     // if there is no decimal, we'll just copy srcStr into strippedStr...simple
  120.     
  121.     if ( !srcHasDecimal )
  122.     {
  123.         HsoipStringCopy( srcStr, strippedStr );
  124.         return; // and we can go home
  125.     }
  126.     
  127.     // here's the fun...if there is a decimal (and we'll only assume the first period
  128.     // in the string...if there are mor periods in the string, oh well....) we'll have
  129.     // a little fun manipulating things.
  130.     
  131.     // first, just straight copy over from srcStr to strippedStr until we hit the decimal
  132.     // (nicely enough, "i" holds the "exact location" of where the decimal is)
  133.     
  134.     for ( j = 1; j < i; j++ )
  135.         strippedStr[j] = srcStr[j];
  136.     
  137.     // and now we skip over the decimal and continue copying until we're done
  138.     
  139.     for ( j = i + 1; j <= srcStr[0]; j++ )
  140.         strippedStr[j - 1] = srcStr[j];
  141.     
  142.     // and finally, the Pascal string needs a length byte
  143.     
  144.     strippedStr[0] = srcStr[0] - 1;
  145.     
  146.  
  147.     return;
  148. }
  149.  
  150. // HsoipCopy is a port of the MyCopy function from Tom Bender's Text-Edit+ 1.6.3
  151. // says Tom: this function is used to replace the standard MW copy function because the
  152. // MW function returns a null string if start or count are out of range.  This function
  153. // pins the start or count to allowable values.
  154. // the original Pascal prototype looked like this:
  155. // function MyCopy( source: string; start, cout: integer): string;
  156. // i've obviously modifed this slightly
  157.  
  158. void    HsoipCopy( Str255 src, short start, short count, Str255 dest )
  159. {
  160.     // pin start to allowable value
  161.     
  162.     if ( start < 1 )
  163.     {
  164.         count -= (1 - start);
  165.         start = 1;
  166.     }
  167.     
  168.     // pin count to allowable values
  169.     
  170.     if ( (start + count) > src[0] )
  171.         count = src[0] - start + 1;
  172.     if ( count < 0 )
  173.         count = 0;
  174.     
  175.     // now do the actual copy
  176.     
  177.     src[0] = count;
  178.     BlockMoveData( &src[start], &src[1], count );
  179.     HsoipStringCopy( src, dest );
  180.     
  181.     return;
  182. }
  183.         
  184. #pragma mark -
  185. #pragma mark ••• Pascal Operator Functions (In C) •••
  186.  
  187. /*
  188.     what follows are a bunch of C ports of a lot of common Pascal operator functions.
  189.     they're not used everywhere in HAS, but included here cause someday you might
  190.     find them useful and handy.  besides, so much of the MacOS was originally
  191.     done in Pascal, these probably will be useful to you in someway.
  192.     
  193.     i acquired them from Ken Long (kenlong@netcom.com), who's always been a kind,
  194.     helpful person to the Mac programming community.  Thanx Ken!  Oh, and as for
  195.     who wrote these, Ken told me that it wasn't him that wrote them, but
  196.     someone with the initials of SKA (apparently this person was porting some
  197.     Pascal code, i think Tom Bender's Tex-Edit code ironicly enough, and
  198.     wrote these...Ken acquired them when he got a copy of a C port of Tex-Edit).
  199.     Hopefully no one will mind me using them here.
  200.     
  201.     usage of these functions should be pretty self-explanitory.  if not, try
  202.     looking them up in any Pascal language reference (for example, the QuickView
  203.     database that came with CW7).  it'll be the same deal.
  204.     
  205.     and tho the rest of HAS uses the "HsoiXxx" naming convention for functions,
  206.     due to these being really Pascal functions, i'm leaving their names as is
  207.     to make it easier.
  208. */
  209.  
  210. // utils.c
  211. // Added by SKA for misc utility functions
  212. // All strings are assumed Pascal strings (with length in first byte)
  213. // No error checking is done for string overflow beyond 255 chars
  214.  
  215. Boolean isAlpha(char ch)
  216. {
  217.     return ('A' <= ch && ch <= 'Z' || 'a' <= ch && ch <= 'z');
  218. }
  219.  
  220. Boolean isLower(char ch)
  221. {
  222.     return ('a' <= ch && ch <= 'z');
  223. }
  224.  
  225. Boolean isUpper(char ch)
  226. {
  227.     return ('A' <= ch && ch <= 'Z');
  228. }
  229. // if you're curious what some of these numbers are in these functions, check
  230. // your handy ASCII character chart...these are the decimal equivalents of these
  231. // unprintable characters (fyi, THINK Reference has an ASCII chart in it)
  232.  
  233. Boolean isSeparator(char ch)
  234. {
  235.     /*    I will try to translate this down for those without an ASCII chart.
  236.         all numeric values (both in the translation and the code) are in decimal
  237.         (not hex or octal)
  238.         
  239.         if the character is a non-printable control character (31 or less) or
  240.         one of these: 'space' ! " # $ % & ' ( ) * + , - . / (47 or less) OR
  241.         the char is greater than or equal to a : (between 48 and 57 inclusive
  242.         are the digits 0-9) AND less than a ? (: ; < = > ? are 58-63) OR
  243.         between 91 and 95 inclusive ([ \ ] ^ _) OR is { OR | or } or between
  244.         208 and 212 (these are unprintable here, but 208 and 209 i dunno what
  245.         they are, 210 is the left smart quote, 211 is the right smart quote, and
  246.         212 is the smart apostrophe)
  247.         
  248.         then return true :)
  249.     
  250.         basically, anything not a "letter" will return true, letters return false.
  251.         
  252.         but, this can greatly vary (actually) depending on how the font is set up.
  253.         the ASCII standards (below 128) will be for sure, but who knows what anything
  254.         in the non-standard set will return since there are a lot of non-character
  255.         things abover 128 that should return true, but again can vary from font to font.
  256.     */
  257.     return (ch < 48 || 58 <= ch && ch <= 63 || 91 <= ch && ch <= 95 ||
  258.                 ch == 123 || ch == 124 || ch == 125 || 208 <= ch && ch <= 212);
  259. }
  260.  
  261. Boolean isNonquoteSeparator(char ch)
  262. {
  263.     return (ch != '\'' && isSeparator(ch));
  264. }
  265.  
  266. Boolean isSentenceEnder(char ch)
  267. {
  268.     return (ch == '\t' || ch == 12 || ch == '\r' || ch == ' ' || ch == '!' ||
  269.                 ch == '.' || ch == '?' || ch == 201);
  270. }
  271.  
  272. Boolean isSentenceStarter(char ch)
  273. {
  274.     return (ch == '\t' || ch == '\r' || ch == ' ');
  275. }
  276.  
  277. char UprChar(char ch, Boolean diac)
  278. {
  279.     Str255 s;
  280.     
  281.     s[0] = 1; s[1] = ch;
  282.     UpperString(s, diac);
  283.     return s[1];
  284. }
  285.  
  286. // returns position of 1st occurrence of ch in str, 0 if none
  287. short charPos(char ch, Str255 str)
  288. {
  289.     register short i, lstr;
  290.     
  291.     lstr = *str++;
  292.     for (i = 1; i <= lstr && str[i] != ch; i++)
  293.         ;
  294.     return (i <= lstr ? i : 0);
  295. }
  296.  
  297. // returns position of 1st occurrence of pat in str, 0 if none
  298. short pos(Str255 pat, Str255 str)
  299. {
  300.     register short i, j, k, lstr, lpat;
  301.     
  302.     lstr = *str;  lpat = *pat;
  303.     for (i = 1; i <= lstr; i++) {
  304.         for (j = i, k = 1; k <= lpat && str[j] == pat[k]; j++, k++)
  305.             ;
  306.         if (k > lpat)
  307.             return i;
  308.     }
  309.     return 0;
  310. }
  311.  
  312. void copyStr (Str255 dest, Str255 src)
  313. {
  314.     register short        len;
  315.     
  316.     len = src[0];
  317.     while (len-- >= 0) *dest++ = *src++;
  318. }
  319.      
  320. void copySubStr (Str255 dest, Str255 src, short first, short len)
  321. {
  322.     unsigned char    *src1;
  323.     
  324.     *dest++ = (unsigned char) len;
  325.     src1 = src+first;
  326.     while (len--) *dest++ = *src1++;
  327. }
  328.      
  329. void concat(Str255 dest, Str255 str1, Str255 str2)
  330.  
  331.     register short    len;
  332.     
  333.     *dest++ = (len = *str1++) + *str2;
  334.     while (len--) *dest++ = *str1++;
  335.     len = *str2++;
  336.     while (len--) *dest++ = *str2++;
  337. }    
  338.     
  339. void insert(Str255 str, Str255 src, short i)
  340. {
  341.     register short j, p, q, lstr, lsrc;
  342.     
  343.     lstr = str[0]; lsrc = src[0];
  344.     lsrc += lstr;
  345.     if (lstr+lsrc <= 255) {
  346.         for (p = lsrc, q = lsrc-lstr; q >= i; p--, q--)
  347.             str[p] = str[q];
  348.         for (j = 0, p = i, q = 1; j < lsrc; j++)
  349.             str[p++] = src[q++];
  350.     }
  351. }
  352.  
  353. void append(Str255 dest, Str255 str)
  354. {
  355.     register short i, j, len;
  356.     
  357.     len = str[0];
  358.     i = dest[0]+1;
  359.     for (i = dest[0]+1, j = 1; j <= len; i++, j++)
  360.         dest[i] = str[j];
  361.     dest[0] += len;
  362. }    
  363.  
  364. // originally, this function was called "delete" (as is the pascal function of the
  365. // same name).  however, "delete" is also a reserved keyword in certain languages
  366. // (like C++) and could pose some compiler errors.  Due to this fact, this function
  367. // has been renamed "pDelete" (for "Pascal delete")
  368.     
  369. void pDelete(Str255 str, short i, short len)
  370. {
  371.     register short j, k, lstr;
  372.     
  373.     lstr = str[0];
  374.     if (i <= lstr && lstr >= i+len-1) {
  375.         str[0] = lstr - len;
  376.         for (j = 0, k = i+len; j < len; j++, i++, k++)
  377.             str[i] = str[k];
  378.     }
  379. }
  380.  
  381. OSType packString(Str255 str)
  382. {
  383.     OSType a;
  384.     
  385.     a = ((long) str[1] << 24) | ((long) str[2] << 16) | (str[3] << 8) | str[4];
  386.     return a;
  387. }
  388.  
  389. void unpackOSType(OSType a, Str255 str)
  390. {
  391.     long mask = 0xFF;
  392.     
  393.     str[0] = 4;
  394.     str[1] = a >> 24;
  395.     str[2] = (a >> 16) & mask;
  396.     str[3] = (a >> 8) & mask;
  397.     str[4] = a & mask;
  398. }
  399.